unit illusb;


interface


uses

  Windows, Messages, SysUtils, Classes, Forms;


type


  PDevBroadcastHdr  = ^DEV_BROADCAST_HDR;

  DEV_BROADCAST_HDR = packed record

    dbch_size: DWORD;

    dbch_devicetype: DWORD;

    dbch_reserved: DWORD;

  end;


  PDevBroadcastDeviceInterface  = ^DEV_BROADCAST_DEVICEINTERFACE;

  DEV_BROADCAST_DEVICEINTERFACE = record

    dbcc_size: DWORD;

    dbcc_devicetype: DWORD;

    dbcc_reserved: DWORD;

    dbcc_classguid: TGUID;

    dbcc_name: array [0..255] of char;

  end;


const

  GUID_DEVINTERFACE_USB_DEVICE: TGUID =

'{A5DCBF10-6530-11D2-901F-00C04FB951ED}';

  DBT_DEVICEARRIVAL          = $8000;          // system detected a new     device

  DBT_DEVICEREMOVECOMPLETE   = $8004;          // device is gone

  DBT_DEVTYP_DEVICEINTERFACE = $00000005;      // device interface class


type


  TComponentUSB = class(TComponent)

  private

    FWindowHandle: HWND;

    FOnUSBArrival: TNotifyEvent;

    FOnUSBRemove: TNotifyEvent;

    fDeviceName:String;

    procedure WndProc(var Msg: TMessage);

    function USBRegister: Boolean;

  protected

    procedure WMDeviceChange(var Msg: TMessage); dynamic;

  public

    property DeviceName:String read FDeviceName;

    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

  published

    property OnUSBArrival: TNotifyEvent read FOnUSBArrival write

FOnUSBArrival;

    property OnUSBRemove: TNotifyEvent read FOnUSBRemove write FOnUSBRemove;

  end;

procedure Register;

implementation


procedure Register;   { add this in the implementation section }

begin

  RegisterComponents('Samples', [TComponentUSB]);

end;



constructor TComponentUSB.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  FWindowHandle := AllocateHWnd(WndProc);

  USBRegister;

end;


destructor TComponentUSB.Destroy;

begin

  DeallocateHWnd(FWindowHandle);

  inherited Destroy;

end;


procedure TComponentUSB.WndProc(var Msg: TMessage);

begin

  if (Msg.Msg = WM_DEVICECHANGE) then

  begin

    try

      WMDeviceChange(Msg);

    except

      Application.HandleException(Self);

    end;

  end

  else

    Msg.Result := DefWindowProc(FWindowHandle, Msg.Msg, Msg.wParam,

Msg.lParam);

end;


procedure TComponentUSB.WMDeviceChange(var Msg: TMessage);

var

  devType: Integer;

  Datos: PDevBroadcastHdr;

begin

  if (Msg.wParam = DBT_DEVICEARRIVAL) or (Msg.wParam =

DBT_DEVICEREMOVECOMPLETE) then

  begin

    Datos := PDevBroadcastHdr(Msg.lParam);

    devType := Datos^.dbch_devicetype;

    if devType = DBT_DEVTYP_DEVICEINTERFACE then

    begin // USB Device

      if Msg.wParam = DBT_DEVICEARRIVAL then

      begin

        if Assigned(FOnUSBArrival) then

          FOnUSBArrival(Self);

      end

      else

      begin

        if Assigned(FOnUSBRemove) then

          FOnUSBRemove(Self);

      end;

    end;

  end;

end;


function TComponentUSB.USBRegister: Boolean;

var

  dbi: DEV_BROADCAST_DEVICEINTERFACE;

  Size: Integer;

  r: Pointer;

begin

  Result := False;

  Size := SizeOf(DEV_BROADCAST_DEVICEINTERFACE);

  ZeroMemory(@dbi, Size);

  dbi.dbcc_size := Size;

  dbi.dbcc_devicetype := DBT_DEVTYP_DEVICEINTERFACE;

  dbi.dbcc_reserved := 0;

  dbi.dbcc_classguid  := GUID_DEVINTERFACE_USB_DEVICE;

  dbi.dbcc_name := dbi.dbcc_name;

  fDeviceName := String(dbi.dbcc_name);

  r := RegisterDeviceNotification(FWindowHandle, @dbi,

    DEVICE_NOTIFY_WINDOW_HANDLE

    );

  if Assigned(r) then Result := True;

end;


end.

